import os
import socket

from xbase_util.common_util import setup_logger
from xbase_util.esreq import EsReq
from xbase_util.geo_util import GeoUtil

from src.bean.statistic_column import StatisticColumn
from src.bean.vulnerability_enum import VulnerabilityEnum
from src.col_bean.dangerous_enum import ColDangerousEnum
from src.col_bean.dns_domain_enum import ColDnsDomainEnum
from src.col_bean.entropy_field_enum import ColEntropyFieldEnum
from src.col_bean.geo_field_enum import ColGeoFieldEnum
from src.col_bean.other_field_enum import ColOtherFieldEnum
from src.col_bean.status_code_count_field_enum import ColStatusCodeCountFieldEnum
from src.col_bean.time_field_enum import ColTimeFieldEnum
from src.value_bean.value_dangerous_enum import ValueDangerousEnum
from src.value_bean.value_dns_domain_enum import ValueDnsDomainEnum
from src.value_bean.value_geo_field_enum import ValueGeoFieldEnum
from src.value_bean.value_other_field_enum import ValueOtherFieldEnum
from src.value_bean.value_payload_visible_enum import ValuePayloadVisibleEnum

req = EsReq("http://10.28.1.140:9200", timeout=200)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
    # 连接一个外部地址，实际不会发送数据
    s.connect(("8.8.8.8", 80))
    ip = s.getsockname()[0]
finally:
    s.close()
server = None
if ip == '10.28.1.140':
    server = 140
    print("正在140上运行")
    pcap_path_prefix = 'origin'
elif ip == '10.28.6.144':
    server = 144
    print("正在144上运行")
    pcap_path_prefix = '/mnt/'
else:
    print(f"当前IP:{ip},请确保程序在140或144上运行")
    pcap_path_prefix = ''
global_geo_util = GeoUtil()
expression = {
    'web': 'host.http == groupama-sdig.com',
    'app': 'ip.src == 10.28.6.109||ip.src == 10.28.6.110||ip.src == 10.28.6.111||ip.src == 10.28.6.112||ip.src == 10.28.6.113||ip.src==10.28.6.117||ip.src==10.28.6.118||ip.dst == 10.28.6.109||ip.dst == 10.28.6.110||ip.dst == 10.28.6.111||ip.dst == 10.28.6.112||ip.dst == 10.28.6.113||ip.dst==10.28.6.117||ip.dst==10.28.6.118',
    'oa': 'ip.dst != 10.28.7.0/24 && host.http == oa.groupama-sdig.com',
    'internet': 'ip.src != 10.0.0.0/8 && ip.src != 192.0.0.0/8 && ip.protocol == tcp',
    'internet_entry': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8',
    # video_server_from_internet数据预测结果：异常有8个|正常有697754个
    'video_server_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http == videoserver.groupama-sdig.com',
    'motor_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http ==motor.groupama-sdig.com',
    'dztbdapp_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http ==dztbdapp-prod.groupama-sdig.com',
    'shoukuan_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http ==shoukuan.groupama-sdig.com',
    'uba_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http ==uba.groupama-sdig.com',
    'rpa_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http ==rpa.groupama-sdig.com',
    'channel_in_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http ==channel-in.groupama-sdig.com',
    'racall_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http ==racall.groupama-sdig.com',
    'other_from_internet': 'ip.xff == EXISTS! && ip.xff != 10.28.9.146/8 && ip.xff != 192.103.16.192/8 && host.http != videoserver.groupama-sdig.com&& host.http !=motor.groupama-sdig.com&& host.http !=dztbdapp-prod.groupama-sdig.com&& host.http !=shoukuan.groupama-sdig.com&& host.http !=uba.groupama-sdig.com && host.http !=rpa.groupama-sdig.com && host.http !=channel-in.groupama-sdig.com&& host.http!=racall.groupama-sdig.com',
    "scan": "ip.src == 10.255.76.196 && host.http == oa.groupama-sdig.com"
}
expression_tag = 'scan'
field_map = {
    ColGeoFieldEnum.sip_geo_country_iso.value: ValueGeoFieldEnum.ip_no_value.value,
    ColGeoFieldEnum.sip_geo_province_name.value: ValueGeoFieldEnum.ip_no_value.value,
    ColGeoFieldEnum.sip_geo_city_name.value: ValueGeoFieldEnum.ip_no_value.value,

    ColGeoFieldEnum.dip_geo_country_iso.value: ValueGeoFieldEnum.ip_no_value.value,
    ColGeoFieldEnum.dip_geo_province_name.value: ValueGeoFieldEnum.ip_no_value.value,
    ColGeoFieldEnum.dip_geo_city_name.value: ValueGeoFieldEnum.ip_no_value.value,

    ColGeoFieldEnum.xffip_geo_country_iso.value: ValueGeoFieldEnum.ip_no_value.value,
    ColGeoFieldEnum.xffip_geo_province_name.value: ValueGeoFieldEnum.ip_no_value.value,
    ColGeoFieldEnum.xffip_geo_city_name.value: ValueGeoFieldEnum.ip_no_value.value,

    ColStatusCodeCountFieldEnum.status_code_1x_count.value: -1,
    ColStatusCodeCountFieldEnum.status_code_2x_count.value: -1,
    ColStatusCodeCountFieldEnum.status_code_3x_count.value: -1,
    ColStatusCodeCountFieldEnum.status_code_4x_count.value: -1,
    ColStatusCodeCountFieldEnum.status_code_5x_count.value: -1,
    ColTimeFieldEnum.session_time_diff.value: 0,
    ColTimeFieldEnum.session_per_packet_req_time_mean.value: 0,
    ColTimeFieldEnum.session_per_packet_res_time_mean.value: 0,
    ColTimeFieldEnum.per_packet_req_time.value: 0,
    ColTimeFieldEnum.per_packet_res_time.value: 0,
    ColTimeFieldEnum.session_per_packet_time_mean.value: 0,
    ColOtherFieldEnum.req_payload_visible.value: ValuePayloadVisibleEnum.PAYLOAD_INVISIBLE.value,
    ColOtherFieldEnum.res_payload_visible.value: ValuePayloadVisibleEnum.PAYLOAD_INVISIBLE.value,
    ColOtherFieldEnum.req_has_payload.value: ValuePayloadVisibleEnum.WITHOUT_PAYLOAD.value,
    ColOtherFieldEnum.res_has_payload.value: ValuePayloadVisibleEnum.WITHOUT_PAYLOAD.value,
    ColDnsDomainEnum.dns_domain.value: ValueDnsDomainEnum.dns_no_domain.value,
    ColOtherFieldEnum.req_transfer_encoding.value: ValueOtherFieldEnum.none.value,
    ColOtherFieldEnum.res_transfer_encoding.value: ValueOtherFieldEnum.none.value,
    ColOtherFieldEnum.req_content_encoding.value: ValueOtherFieldEnum.none.value,
    ColOtherFieldEnum.res_content_encoding.value: ValueOtherFieldEnum.none.value,
    ColOtherFieldEnum.req_uri.value: '',
    ColOtherFieldEnum.packet_no_res.value: False,
    ColOtherFieldEnum.res_status_code.value: 0,
    ColOtherFieldEnum.req_method.value: '',
    ColOtherFieldEnum.req_res_packet_len_rate.value: 0,
    ColOtherFieldEnum.res_req_packet_len_rate.value: 0,
    ColEntropyFieldEnum.per_packet_req_body.value: 0.0,
    ColEntropyFieldEnum.per_packet_res_body.value: 0.0,
    ColEntropyFieldEnum.per_packet_all_body.value: 0.0,
    ColEntropyFieldEnum.session_req_body.value: 0.0,
    ColEntropyFieldEnum.session_res_body.value: 0.0,
    ColEntropyFieldEnum.session_all_body.value: 0.0,
    ColEntropyFieldEnum.per_packet_uri.value: 0.0,
    ColEntropyFieldEnum.dns_domain.value: 0.0,
    ColDangerousEnum.deny_method.value: ValueDangerousEnum.normal.value,
    ColDangerousEnum.protocol.value: ValueDangerousEnum.normal.value,
    ColDangerousEnum.severity.value: ValueDangerousEnum.normal.value,
    ColDangerousEnum.threat_summary.value: ValueDangerousEnum.normal.value,
    ColDangerousEnum.traffic_type.value: ValueDangerousEnum.normal.value,
    ColDangerousEnum.is_dangerous.value: False,
}
# 用于判断威胁的字段初始值都是空字符串
for item in VulnerabilityEnum.get_default_value_map():
    field_map[item] = ''
# 统计字段初始值都是0
for item in StatisticColumn.columns.value:
    field_map[item] = 0
current_dir = os.path.dirname(__file__)
project_root_path = os.path.join(current_dir, "..")
vector_file_path = os.path.join(project_root_path, 'model', 'vector_file.pkl')
capture_logger = setup_logger("capture", "log")
predict_logger = setup_logger("predict", "log")
# 1，列一样的去掉
# http.request-referer单独分词 (3,6) max_features=10
# 其他随机字符列表用单独分词，固定长度
drop_columns = ["id", "node", "packetPos", "dangerous_deny_method", "dangerous_protocol",
                "dangerous_severity", "dangerous_threat_summary", "dangerous_traffic_type", "geo_country_iso",
                "geo_province_name", "geo_city_name", "firstPacket", "lastPacket", "dns.ip", "source.port",
                "source.ip", "destination.ip", "destination.port",
                "http.requestHeader", "http.responseHeader", "http.keyCnt", "http.key",
                "http.hostTokens", "firstPacket_datetime", "lastPacket_datetime", "http.uri"]
same_value = ['node', 'ipProtocol', 'dns.ASN', 'dns.RIR', 'dns.GEO', 'dns.alpn', 'dns.alpnCnt',
              'dns.ip', 'dns.ipCnt', 'dns.OpCode', 'dns.OpCodeCnt', 'dns.Puny', 'dns.PunyCnt', 'dns.QueryClass',
              'dns.QueryClassCnt', 'dns.QueryType', 'dns.QueryTypeCnt', 'dns.status', 'dns.hostCnt', 'dns.host',
              'dns.statusCnt', 'tls.cipher', 'tls.cipherCnt', 'tls.dstSessionId', 'tls.ja3s', 'tls.ja3sCnt',
              'tls.srcSessionId', 'tls.version', 'tls.versionCnt', 'tls.ja4_r', 'tls.ja4_rCnt', 'geo_country_iso',
              'geo_province_name', 'geo_city_name', 'dns.domain', 'entropy_dns_domain',
              'UserAgent_is_unknown']
high_dup_cols = ['segmentCnt',
                 'tls.ja3', 'tls.ja3Cnt',
                 'tls.ja4', 'tls.ja4Cnt', 'status_code_1x_count']

file_suffix_keyword = [
    ".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".ico", ".bmp", ".tiff", ".avif", ".heic",
    ".mp3", ".wav", ".ogg", ".flac", ".aac", ".m4a", ".weba",
    ".mp4", ".webm", ".avi", ".mov", ".mkv", ".flv", ".wmv", ".m4v", ".ts", ".3gp",
    ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt",
    ".pptx", ".odt", ".ods", ".odp", ".txt", ".rtf", ".md", ".csv",
    ".html", ".htm", ".css", ".js", ".xhtml", ".rss",
    ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", ".xz", ".zst",
    ".woff", ".woff2", ".ttf", ".otf", ".eot", ".apk",
    ".swf", ".fla", ".blend", ".dae", ".glb", ".gltf",
    ".webmanifest", ".appcache", "icon", "ico", "appico", "m3u8"
]

content_type_has_binary = ['vnd.', 'excel', 'xlsx', 'javascript', 'font', 'ttf', 'otf', 'video', 'audio', 'image',
                           'pdf']
update_local_cache = True
hide_log = False
remove_missing_data_when_train = True
